#include "stdafx.h"
#include "TypeBNCU.h"
TypeBNCU::TypeBNCU():
GeneralNCU(TypeB)
{
}
TypeBNCU::TypeBNCU(const unsigned int &config):
GeneralNCU(TypeB,config), TypeANCU(config)
{
}
TypeBNCU::TypeBNCU(const unsigned int &config,
				   const vector<double> &paras):
GeneralNCU(TypeB,config), TypeANCU(config)
{
	parameters(paras);
}
TypeBNCU::TypeBNCU(const TypeBNCU &rhs):
GeneralNCU(rhs), TypeANCU(rhs), m_SingleVent(rhs.m_SingleVent)
{
}
TypeBNCU& TypeBNCU::operator=(const TypeBNCU &rhs)
{
	if ( this != &rhs)
	{
		TypeANCU::operator =(rhs);
		m_SingleVent = rhs.m_SingleVent;
	}
	return (*this);
}
TypeBNCU::~TypeBNCU()
{
}
/*********************************************
	Configuration Section
*********************************************/
// get the number of parameters of a NCU
const unsigned int TypeBNCU::number() const
{
	return ((2*nSequence())+ 2);
}
/*********************************************
	Parameters Section
*********************************************/
// assign all parametrs of a NCU
bool TypeBNCU::parameters(const vector<double> &paras)
{
	if ( paras.size() != number() )
	{
		errMsg = msg[2];
		return false;
	}
	else
	{
		vector<double>::const_iterator iter = paras.begin();
		initialSill(*iter);  // assign the value of the initial sill
		reset(); // set the value of the current sill to the value of the initial sill
		++ iter;
		m_SingleVent.VentCoe(*iter); // assign the value of the single lateral output
		++ iter;
		vector<double> tmp(iter, paras.end());
		sequence(tmp); // assign the values of the sequence of the lateral output
		return true;
	}
}
// get all parameters of a NCU
vector<double> TypeBNCU::parameters() const
{
	vector<double> paras, tmp;
	paras.push_back(TypeANCU::initialSill());
	paras.push_back(
		m_SingleVent.VentCoe()
		);
	tmp = TypeANCU::sequence().parameters();
	paras.insert(paras.end(), tmp.begin(), tmp.end());
	return paras;
}
// virtual constructor
GeneralNCU* TypeBNCU::clone() const
{
	return new TypeBNCU(*this);
}
// get the genome information
// simulation
outputPair TypeBNCU::simulation(const double &input)
{
	update(input);
	outputPair flow;
	flow.first = output(currentSill());
	flow.second = bottom(currentSill());
	currentSill(
		currentSill() - flow.first
		);
	return flow;
}
double TypeBNCU::output(const double &sill)
{
	return (
		TypeANCU::output(sill)+
		m_SingleVent.output(sill)
		);
}
vector<const GenomeType*> TypeBNCU::genome() const
{
	vector<const GenomeType*> tmp = TypeANCU::genome();
	// insert the single vent output into the genome set
	vector<const GenomeType*>::iterator loc = tmp.begin();
	++loc;
	tmp.insert( loc, &genomeSet().GetVentGenome() ); 
	return tmp;
}